﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic.Sync ;
using System.Runtime.Serialization ;
namespace WayneGameSolution.Packs
{
    [DataContract]
    [Serializable]
   public abstract partial   class DataPack:IDataPack  ,ISerializableSlim 
    {

       public DataPack(int flag)
       {
           PackType = this.GetType();
           Flag = flag; 
       }



       static public IDictionary<int, Type> PackFlagNameDictionary;
       static private Microsoft.Practices.Unity.UnityContainer Container;
           static DataPack()
       {
           PackFlagNameDictionary = new SyncDictionaryProxty<int, Type>(new SortedDictionary<int, Type>());
           Container = new Microsoft.Practices.Unity.UnityContainer();
           AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad_ForPackReg);
           AppDomain.CurrentDomain.GetAssemblies().ForEach((o, i) => DealWithAsmForPackReg(o));
       
       }
       static public DataPack Create(int flag)
       {
           return Container.Resolve(PackFlagNameDictionary[flag]) as DataPack;
       
       }
       private     static void CurrentDomain_AssemblyLoad_ForPackReg(object sender, AssemblyLoadEventArgs args)
       {
           DealWithAsmForPackReg(args.LoadedAssembly);
       }

       
        static void  DealWithAsmForPackReg(System.Reflection.Assembly asm )
        {
            System.Console.WriteLine("Breakingload : {0}", asm.FullName);
            var types = asm
                .GetTypes()
                .Where(t => t.IsSubclassOf(typeof(WayneGameSolution.Packs.DataPack)))
                .Where(t => Attribute.IsDefined(t, typeof(PackFlagAttribute)))
                .ToList();

            types.ForEach(
                    t =>
                    {
                        var atrb=Attribute.GetCustomAttribute(t, typeof(PackFlagAttribute)) as PackFlagAttribute;
                        if (atrb != null)
                        {
                            PackFlagNameDictionary[atrb.Flag]= t ;
                            Container.RegisterType(typeof(DataPack), t, atrb.PackName);
                        }
                    }
                );


           
                
            
            
        
        }


        [System.Xml.Serialization.XmlIgnore()]
        public WayneGameSolution.Membership.IUser ExecuteUser
        {
            get;
            set;

        }




        #region IPack Members

        public Type PackType
        {
            get;
            set;
        }

        public int Flag
        {
            get;
            set;
        }



        public int TrackId
        {
            get;
            set;
        }

        #endregion





        #region IDataPack Members

       [System.Xml.Serialization.XmlIgnore()]
        abstract public IPackNode DataRoot { get;  }


        #endregion

       #region ISerializablePack Members

       abstract public void GetObjectData(SerializationInfo info, StreamingContext context);
 

       abstract public void SetObjectData(SerializationInfo info, StreamingContext context);

       #endregion
    }
   [global::System.AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false )]
   public  class PackFlagAttribute : Attribute
   {
 


       public PackFlagAttribute(string packName,int flag)
       {

           this.Flag = flag;
           this.PackName = packName;
         
       }

       public int Flag
       {
           get;
           private set;
       }
       public string PackName
       {
           get;
           private set;
       }


   }
}
